package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.constant.CommonConstant;
import com.ruoyi.system.constant.ExceptionConstant;
import com.ruoyi.system.domain.OrderInitiate;
import com.ruoyi.system.domain.OrderLink;
import com.ruoyi.system.domain.OrderLinkRealize;
import com.ruoyi.system.domain.OrderOperation;
import com.ruoyi.system.mapper.OrderInitiateMapper;
import com.ruoyi.system.mapper.OrderLinkMapper;
import com.ruoyi.system.mapper.OrderLinkRealizeMapper;
import com.ruoyi.system.mapper.OrderOperationMapper;
import com.ruoyi.system.service.IOrderOperationService;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.system.constant.CommonConstant.*;

/**
 * 订单业务列表Service业务层处理
 *
 * @author ruoyi
 * @date 2025-06-12
 */
@Service
public class OrderOperationServiceImpl implements IOrderOperationService {
    private static final Logger Logger = LoggerFactory.getLogger(OrderInitiateServiceImpl.class);
    @Autowired
    private OrderOperationMapper orderOperationMapper;

    @Autowired
    private OrderLinkMapper orderLinkMapper;

    @Autowired
    private OrderInitiateMapper orderInitiateMapper;

    @Autowired
    private OrderLinkRealizeMapper orderLinkRealizeMapper;

    /**
     * 查询订单业务列表详情
     *
     * @param id 订单业务列表主键
     * @return 订单业务列表
     */
    @Override
    public OrderOperation selectOrderOperationById(Long id) {
        try {
            OrderOperation orderOperation = orderOperationMapper.selectOrderOperationById(id);
            // 获取订单信息
            OrderInitiate initiate = orderInitiateMapper
                    .selectOrderInitiateByOrderId(orderOperation.getOrderId());
            if (ObjectUtils.isEmpty(initiate)) {
                throw new RuntimeException(ExceptionConstant.ORDER_NOE_FOUND);
            }
            // 获取订单环节信息-用于获取环节截止时间
            List<OrderLinkRealize> orderLinkRealizes = orderLinkRealizeMapper
                    .selectOrderLinkRealizeListByOrderIds(Collections.singletonList(orderOperation.getOrderId()));
            // 环节map-key：订单id + 环节id + 顺序id（用于查询上一步对应的环节）
            Map<String, OrderLinkRealize> orderLinkRealizeMap = orderLinkRealizes
                    .stream()
                    .distinct()
                    .collect(Collectors.toMap(vo -> String.valueOf(vo.getOrderId()) + vo.getLinkOrder(), s -> s, (key1, key2) -> key1));
            // 环节map-key：订单id + 环节id（用于查询当前对应的环节）
            Map<String, OrderLinkRealize> orderLinkRealizeMapInfo = orderLinkRealizes
                    .stream()
                    .distinct()
                    .collect(Collectors.toMap(vo -> String.valueOf(vo.getOrderId()) + vo.getLinkId(), s -> s, (key1, key2) -> key1));
            // 获取当前环节录入总数量
            OrderOperation orderOperationInfo = new OrderOperation();
            orderOperationInfo.setOrderId(orderOperation.getOrderId());
            orderOperationInfo.setLinkId(orderOperation.getLinkId());
            orderOperationInfo.setStatusList(Collections.singletonList(THREE));
            // 订单名称
            orderOperation.setOrderName(initiate.getOrderName());
            // 当前业务对应的环节信息
            OrderLinkRealize orderLinkRealize = orderLinkRealizeMapInfo.get(String.valueOf(orderOperation.getOrderId()) +
                    orderOperation.getLinkId());
            // 为第一环节时：总数量为订单总数量
            if (orderLinkRealize.getLinkOrder() == 0) {
                orderOperation.setNumber(initiate.getNumber());
            } else {
                // 总数量为上一步环节的合格数量
                orderOperation.setNumber(orderLinkRealizeMap.get(String.valueOf(orderLinkRealize.getOrderId()) +
                        (orderLinkRealize.getLinkOrder() - 1)).getFinishNumber());
            }
            // 完成总数量
            orderOperation.setAccomplishNumber(orderOperationMapper.getAccomplishNumber(orderOperationInfo));
            return orderOperation;
        } catch (Exception e) {
            Logger.error("FAIL selectOrderOperationById error is:{}", e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 待审批
     *
     * @param orderOperation 订单业务列表
     * @return 订单业务列表
     */
    @Override
    public List<OrderOperation> approvalPendingList(OrderOperation orderOperation) {
        try {
            // 将入参名称转为id
            List<Long> orderIds = transformOrderId(orderOperation);
            // 待审核状态
            orderOperation.setStatus(ONE);
            orderOperation.setCreateBy(SecurityUtils.getUsername());
            List<OrderOperation> orderOperations = orderOperationMapper.approvalPendingList(orderOperation, orderIds);
            // 返回数据-显示转换处理
            if (ObjectUtils.isNotEmpty(orderOperations)) {
                forOrderOperations(orderOperations);
            }
            return orderOperations;
        } catch (Exception e) {
            Logger.error("FAIL selectOrderOperationList error is:{}", e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 我的已办
     *
     * @param orderOperation 订单业务列表
     * @return 订单业务列表
     */
    @Override
    public List<OrderOperation> selectOrderOperationList(OrderOperation orderOperation) {
        try {
            // 将入参名称转为id
            List<Long> orderIds = transformOrderId(orderOperation);
            // 只能看到本人创建的
            orderOperation.setCreateBy(SecurityUtils.getUsername());
            List<OrderOperation> orderOperations = orderOperationMapper.selectOrderOperationList(orderOperation, orderIds);
            // 返回数据-显示转换处理
            if (ObjectUtils.isNotEmpty(orderOperations)) {
                forOrderOperations(orderOperations);
            }
            return orderOperations;
        } catch (Exception e) {
            Logger.error("FAIL selectOrderOperationList error is:{}", e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 将名称转为orderId
     *
     * @param orderOperation 订单业务信息
     * @return List
     */
    public List<Long> transformOrderId(OrderOperation orderOperation) {
        if (ObjectUtils.isNotEmpty(orderOperation.getOrderName())) {
            OrderInitiate orderInitiate = new OrderInitiate();
            orderInitiate.setOrderName(orderOperation.getOrderName());
            // 通过环节名称模糊查询订单业务列表
            List<OrderInitiate> orderInitiates = orderInitiateMapper.selectOrderInitiateList(orderInitiate);
            if (ObjectUtils.isEmpty(orderInitiates)) {
                return Collections.EMPTY_LIST;
            }
            return orderInitiates.stream().map(OrderInitiate::getOrderId).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 显示转换（名称等）
     *
     * @param orderOperations 订单业务列表
     */
    public void forOrderOperations(List<OrderOperation> orderOperations) {
        // 相关联订单列表map
        Map<Long, OrderInitiate> orderInitiateMap = new HashMap<>();
        // 相关联环节列表map
        Map<Long, OrderLink> orderLinkMap = new HashMap<>();
        // 取出所有订单id从而获取订单信息
        List<Long> orderIdList = orderOperations.stream().map(OrderOperation::getOrderId).collect(Collectors.toList());
        // 获取订单信息集合
        List<OrderInitiate> initiateList = orderInitiateMapper
                .selectOrderInitiateByOrderIds(orderIdList);
        if (ObjectUtils.isNotEmpty(initiateList)) {
            orderInitiateMap = initiateList.stream()
                    .collect(Collectors.toMap(OrderInitiate::getOrderId, s -> s, (key1, key2) -> key1));
        }
        // 取出所有环节id从而获取订单信息
        List<Long> linkIdList = orderOperations.stream().map(OrderOperation::getLinkId).collect(Collectors.toList());
        // 获取环节信息集合
        List<OrderLink> orderLinks = orderLinkMapper.selectOrderLinkByIds(linkIdList);
        if (ObjectUtils.isNotEmpty(orderLinks)) {
            orderLinkMap = orderLinks.stream()
                    .collect(Collectors.toMap(OrderLink::getId, s -> s, (key1, key2) -> key1));
        }
        // 赋值订单名称和环节名称
        Map<Long, OrderInitiate> finalOrderInitiateMap = orderInitiateMap;
        Map<Long, OrderLink> finalOrderLinkMap = orderLinkMap;
        orderOperations.forEach(vo -> {
            OrderInitiate orderInitiate = finalOrderInitiateMap.get(vo.getOrderId());
            OrderLink orderLink = finalOrderLinkMap.get(vo.getLinkId());
            if (ObjectUtils.isNotEmpty(orderInitiate)) {
                vo.setOrderName(orderInitiate.getOrderName());
            }
            if (ObjectUtils.isNotEmpty(orderLink)) {
                vo.setLinkName(orderLink.getLinkName());
            }
        });
    }

    /**
     * 新增订单业务列表
     *
     * @param orderOperation 订单业务列表
     * @return 结果
     */
    @Override
    public synchronized int insertOrderOperation(OrderOperation orderOperation) {
        try {
            // 判定订单是否存在
            OrderInitiate initiateList = orderInitiateMapper
                    .selectOrderInitiateByOrderId(orderOperation.getOrderId());
            if (ObjectUtils.isEmpty(initiateList)) {
                throw new RuntimeException(ExceptionConstant.ORDER_NOE_FOUND);
            }
            // 当前订单下的所有环节信息
            List<OrderLinkRealize> orderLinkRealizes = orderLinkRealizeMapper.selectOrderLinkRealizeList(orderOperation.getOrderId());
            if (ObjectUtils.isEmpty(orderLinkRealizes)) {
                throw new RuntimeException(ExceptionConstant.ORDER_NOE_FOUND);
            }
            // 环节map-key：订单id + 环节id + 顺序id（用于查询上一步对应的环节）
            Map<String, OrderLinkRealize> orderLinkRealizeMap = orderLinkRealizes
                    .stream()
                    .distinct()
                    .collect(Collectors.toMap(vo -> String.valueOf(vo.getOrderId()) + vo.getLinkOrder(), s -> s, (key1, key2) -> key1));
            // 环节map-key：订单id + 环节id（用于查询当前对应的环节）
            Map<String, OrderLinkRealize> orderLinkRealizeMapInfo = orderLinkRealizes
                    .stream()
                    .distinct()
                    .collect(Collectors.toMap(vo -> String.valueOf(vo.getOrderId()) + vo.getLinkId(), s -> s, (key1, key2) -> key1));
            OrderOperation orderOperationInfo = new OrderOperation();
            BeanUtils.copyProperties(orderOperation, orderOperationInfo);
            List<String> statusList = new ArrayList<>();
            statusList.add(ONE);
            statusList.add(THREE);
            orderOperationInfo.setStatusList(statusList);
            // 待审核 + 已审核通过 的总数量
            Integer number = orderOperationMapper.getAccomplishNumber(orderOperationInfo);
            // 获取校验的最大数量：当前录入数量 + 待审核数量 + 合格数量
            int sumNumber = orderOperation.getInputNumber() + number;
            // 当前业务所对应的环节信息
            OrderLinkRealize orderLinkRealize = orderLinkRealizeMapInfo.get(String.valueOf(orderOperation.getOrderId()) +
                    orderOperation.getLinkId());
            // 排序为0时为第一步：获取校验的最大数量 小于等于 订单总数量
            if (orderLinkRealize.getLinkOrder() == 0) {
                if (sumNumber > initiateList.getNumber()) {
                    throw new RuntimeException(ExceptionConstant.ORDER_LINK_ERROR);
                }
            } else {
                // 对应上一环节的信息
                OrderLinkRealize orderLinkRealizeTopOne = orderLinkRealizeMap.get(String.valueOf(orderLinkRealize.getOrderId()) +
                        (orderLinkRealize.getLinkOrder() - 1));
                // 获取校验的最大数量 小于等于 上一步的合格数量（合格指：审核通过）
                if (sumNumber > orderLinkRealizeTopOne.getFinishNumber()) {
                    throw new RuntimeException(ExceptionConstant.ORDER_LINK_SIZE_ERROR);
                }
            }
            initiateOrderOperation(orderOperation);
            return orderOperationMapper.insertOrderOperation(orderOperation);
        } catch (Exception e) {
            Logger.error("FAIL insertOrderOperation error is:{}", e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 初始化订单业务信息
     *
     * @param orderOperation 订单业务信息
     */
    public void initiateOrderOperation(OrderOperation orderOperation) {
        orderOperation.setCreateTime(DateUtils.getNowDate());
        orderOperation.setUpdateTime(DateUtils.getNowDate());
        orderOperation.setCreateBy(SecurityUtils.getUsername());
        orderOperation.setUpdateBy(SecurityUtils.getUsername());
        orderOperation.setDeleteFlag(CommonConstant.DELETE_FLAG_N);
    }

    /**
     * 修改订单业务列表
     *
     * @param orderOperation 订单业务列表
     * @return 结果
     */
    @Override
    public synchronized int updateOrderOperation(OrderOperation orderOperation) {
        if (ObjectUtils.isEmpty(orderOperation.getId())) {
            throw new RuntimeException(ExceptionConstant.ID_IS_NOT_NULL);
        }
        // 查询当前任务的信息
        OrderOperation operation = orderOperationMapper.selectOrderOperationById(orderOperation.getId());
        if (ObjectUtils.isEmpty(operation)) {
            throw new RuntimeException(ExceptionConstant.DATA_NOT_FOUND);
        }
        if (THREE.equals(operation.getStatus())) {
            throw new RuntimeException(ExceptionConstant.OPERATION_IS_NOT_UPDATE);
        }
        OrderInitiate orderInitiate = orderInitiateMapper.selectOrderInitiateByOrderId(operation.getOrderId());
        if (ObjectUtils.isEmpty(orderInitiate)) {
            throw new RuntimeException(ExceptionConstant.ORDER_NOE_FOUND);
        }
        // 查询订单所属环节信息
        List<OrderLinkRealize> orderLinkRealizes = orderLinkRealizeMapper.selectOrderLinkRealizeList(operation.getOrderId());
        if (ObjectUtils.isEmpty(orderLinkRealizes)) {
            throw new RuntimeException(ExceptionConstant.LINK_NOE_FOUND);
        }
        try {
            // 审核：当前录入数量审核通过，添加完成总数量
            if (THREE.equals(orderOperation.getStatus())) {
                auditProcess(operation, orderInitiate, orderLinkRealizes);
            }
            orderOperation.setUpdateTime(DateUtils.getNowDate());
            orderOperation.setUpdateBy(SecurityUtils.getUsername());
            return orderOperationMapper.updateOrderOperation(orderOperation);
        } catch (Exception e) {
            Logger.error("FAIL updateOrderOperation error is:{}", e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 员工待办-审核
     *
     * @param operation 当前任务信息
     * @param orderInitiate 订单信息
     * @param orderLinkRealizes 订单关联的环节信息
     * @return 结果
     */
    public void auditProcess(OrderOperation operation, OrderInitiate orderInitiate, List<OrderLinkRealize> orderLinkRealizes) {
        // key：环节id，value：环节对象
        Map<Long, OrderLinkRealize> orderLinkRealizeMap = orderLinkRealizes
                .stream().collect(Collectors.toMap(OrderLinkRealize::getLinkId, s -> s, (key1, key2) -> key1));
        // 当前环节已录入数量
        int numberNow = orderLinkRealizeMap.get(operation.getLinkId()).getFinishNumber();
        numberNow = operation.getInputNumber() + (ObjectUtils.isEmpty(numberNow) ? 0 : numberNow);
        OrderLinkRealize orderLinkRealize = new OrderLinkRealize();
        // 当前环节已完成(总录入数量等于总订单数)
        if (orderInitiate.getNumber().equals(numberNow)) {
            // 当前订单已完成环节数量
            List<String> linkStatusList = orderLinkRealizes
                    .stream()
                    .filter(vo -> ONE.equals(vo.getLinkStatus()))
                    .map(OrderLinkRealize::getLinkStatus).collect(Collectors.toList());
            // 最大环节数量 - 已完成环节数量 < 2 时，当前订单已完成
            if (orderLinkRealizes.size() - linkStatusList.size() < 2) {
                OrderInitiate orderInitiateInfo = new OrderInitiate();
                orderInitiateInfo.setId(orderInitiate.getId());
                orderInitiateInfo.setActualFinishTime(DateUtils.getNowDate());
                orderInitiateInfo.setOrderStatus(THREE);
                orderInitiateMapper.updateOrderInitiate(orderInitiateInfo);
            }
            orderLinkRealize.setLinkStatus(ONE);
        }
        orderLinkRealize.setOrderId(operation.getOrderId());
        orderLinkRealize.setLinkId(operation.getLinkId());
        orderLinkRealize.setFinishNumber(numberNow);
        orderLinkRealizeMapper.updateOrderLinkRealize(orderLinkRealize);
    }

    /**
     * 批量删除订单业务列表
     *
     * @param ids 需要删除的订单业务列表主键
     * @return 结果
     */
    @Override
    public int deleteOrderOperationByIds(Long[] ids) {
        return orderOperationMapper.deleteOrderOperationByIds(ids);
    }
}
